package cc.jq1024.domain.activity.repository;

import cc.jq1024.domain.activity.model.aggregate.CreatePartakeOrderAggregate;
import cc.jq1024.domain.activity.model.aggregate.CreateQuotaOrderAggregate;
import cc.jq1024.domain.activity.model.entity.*;
import cc.jq1024.domain.activity.model.valobj.ActivitySkuStockKeyVO;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @Author: jia-qiang ljq1024.cc
 * @desc: 活动仓储接口
 * @Date: 2024-04-22-18:03
 */
public interface IActivityRepository {

    /** 通过sku查询sku信息 */
    ActivitySkuEntity queryActivitySku(Long sku);

    /** 通过活动ID查询活动信息 */
    ActivityEntity queryRaffleActivityByActivityId(Long activityId);

    /** 查询次数信息（用户在活动上可参与的次数） */
    ActivityCountEntity queryRaffleActivityCountByActivityCountId(Long activityCountId);

    /**
     * 交易（下单）接口 - 【无需进行支付】
     * @param createOrderAggregate 订单聚合对象
     */
    void doSaveNoPayOrder(CreateQuotaOrderAggregate createOrderAggregate);

    /**
     * 交易（下单）接口 - 【需要进行支付 - 消耗积分进行兑换】
     * @param createQuotaOrderAggregate 订单聚合对象
     */
    void doSaveCreditPayOrder(CreateQuotaOrderAggregate createQuotaOrderAggregate);

    /** 缓存 sku 活动库存 */
    void cacheActivitySkuStockCount(String cacheKey, Integer stockCount);

    /**
     * 根据 cacheKey，扣减奖品缓存库存
     *
     * @param sku 互动SKU
     * @param cacheKey SKU 缓存 key
     * @param endDateTime 活动结束时间，根据结束时间设置加锁的key为结束时间
     * @return 扣减结果
     */
    boolean subtractionActivitySkuStock(Long sku, String cacheKey, Date endDateTime);

    /** 写入延迟队列，延迟消费更新库存记录 */
    void activitySkuStockConsumeSendQueue(ActivitySkuStockKeyVO activitySkuStockKeyVO);

    /**
     * 获取活动sku库存消耗队列
     *
     * @return 奖品库存Key信息
     * @throws InterruptedException 异常
     */
    ActivitySkuStockKeyVO takeQueueValue() throws InterruptedException;

    /**
     * 清空队列
     */
    void clearQueueValue();

    /**
     * 延迟队列 + 任务 趋势更新活动sku库存
     *
     * @param sku 活动商品
     */
    void updateActivitySkuStock(Long sku);

    /**
     * 缓存库存已消耗完毕，清空数据库库存
     *
     * @param sku 活动商品
     */
    void clearActivitySkuStock(Long sku);

    /**
     * 保存聚合对象 - 一个领域内的一个聚合是一个事务操作
     * @param createPartakeOrderAggregate 参与活动的订单聚合对象
     */
    void saveCreatePartakeOrderAggregate(CreatePartakeOrderAggregate createPartakeOrderAggregate);

    /** 查询没有被使用的活动抽奖订单 */
    UserRaffleOrderEntity queryNoUseRaffleOrder(PartakeRaffleActivityEntity partakeRaffleActivityEntity);

    /** 查询总账户额度 */
    ActivityAccountEntity queryActivityAccountByUserId(String userId, Long activityId);

    /** 查询月账户额度 */
    ActivityAccountMonthEntity queryActivityAccountMonthByUserId(String userId, Long activityId, String month);

    /** 查询日账户额度 */
    ActivityAccountDayEntity queryActivityAccountDayByUserId(String userId, Long activityId, String day);

    /** 根据活动ID查询活动装配的sku列表 */
    List<ActivitySkuEntity> queryActivitySkuListByActivityId(Long activityId);

    /**
     * 查询活动账户 - 日，参与次数
     *
     * @param activityId 活动ID
     * @param userId     用户ID
     * @return 参与次数
     */
    Integer queryRaffleActivityAccountDayPartakeCount(Long activityId, String userId);

    /**
     * 查询活动账户额度「总、月、日」
     *
     * @param activityId 活动ID
     * @param userId     用户ID
     * @return 参与次数
     */
    ActivityAccountEntity queryActivityAccountEntity(Long activityId, String userId);

    /**
     * 查询用户抽奖总次数
     *
     * @param activityId 活动ID
     * @param userId     用户ID
     * @return 抽奖总次数
     */
    Integer queryRaffleActivityAccountPartakeCount(Long activityId, String userId);

    /**
     * 订单出货 - 积分充值
     * @param deliveryOrderEntity 出货单实体对象
     */
    void updateOrder(DeliveryOrderEntity deliveryOrderEntity);

    /** 查询未支付订单 */
    UnpaidActivityOrderEntity queryUnpaidActivityOrder(SkuRechargeOrderEntity skuRechargeEntity);

    /**
     * 查询当前活动ID下，创建的 sku 商品。「sku可以兑换活动抽奖次数」
     * @param activityId 活动ID
     * @return 返回sku商品集合
     */
    List<SkuProductEntity> querySkuProductEntityListByActivityId(Long activityId);

    /** 查询用户当前账户积分余额 */
    BigDecimal queryUserCreditAccountAmount(String userId);
}
